#include <iostream>
#include <zlib/eventsystem/I_EventSystem.h>
#include <unistd.h>

using namespace std;


EThread t1(1);
EThread t2(2);

class TestCont : public Continuation
{
public:
	TestCont() : number(0)
	{
		time = ink_get_base_hrtime_internal();	
		cout << "Construct function  TestCont" << endl;
		SET_HANDLER(&TestCont::mainHandler);
	}

	int mainHandler(int event, void *data)
	{
		Event *e = (Event *)data;

		if(event == EVENT_IMMDIATE) {
			cout << "main Handler, immdiate function" << endl;
			SET_HANDLER(&TestCont::t1_Handler);
			e->ethread->schedule_imm(this);
		}else if(event == EVENT_INTERVAL){
			cout << "main Handler, interval function" << endl;
			SET_HANDLER(&TestCont::t2_Handler);
			e->ethread->schedule_imm(this);
		}else if(event == EVENT_POLL){
			cout << "main Hnadler, poll function" << endl;
		}

		return EVENT_CONT;
	}

	int t1_Handler(int event, void *data)
	{
		Event *e = (Event *)data;
		
		if(event == EVENT_IMMDIATE) {
			cout << "t1 Handler, immdiate function" << endl;
			SET_HANDLER(&TestCont::t1_Handler);
			t1.schedule_every(this, ink_hrtime_from_msecond(2));
			t2.schedule_every(this, ink_hrtime_from_msecond(2));
		}else if(event == EVENT_INTERVAL){
			cout << "t1 Handler, interval function" << endl;
			goto exec_t1;
		}else if(event == EVENT_POLL){
			cout << "t1 Hnadler, poll function" << endl;
		}
exec_t1:
		if(number >= 100000)
		{
			cout << "t1 " << "the number is " << number << endl;
			cout << "time:" << ink_get_base_hrtime_internal() - time << endl;
			e->cancle_action();
			delete this;
			return EVENT_DONE;
		}

		number++;
		cout << "+++++++++++++++" << endl;
		return EVENT_CONT;
	}

	int t2_Handler(int event, void *data)
	{
		Event *e = (Event *)data;
		
		if(event == EVENT_IMMDIATE) {
			cout << "t2 Handler, immdiate function" << endl;
			e->ethread->schedule_at(this, ink_hrtime_from_msecond(2));
		}else if(event == EVENT_INTERVAL){
			cout << "t2 Handler, interval function" << endl;
			e->ethread->schedule_every(this, -ink_hrtime_from_msecond(2));
		}else if(event == EVENT_POLL){
			cout << "t2 Hnadler, poll function" << endl;
			goto exec_t2;
		}

exec_t2:
		if(number >= 100000)
		{
			cout << "t2 " << "the number is " << number << endl;
			e->cancle_action();
			delete this;
			return EVENT_DONE;
		}

		number++;
		return EVENT_CONT;
	}

	int number;
	ink_hrtime time;
};

class DCont : public Continuation
{
public:
	DCont()
	{
		cout << "construct function" << endl;
		SET_HANDLER(&DCont::mainHandler);
	}

	int mainHandler(int event, void *data)
	{
		for(int i = 0; i < 10; i++)
		{
			cout << "DCont main Handler" << endl;
			sleep(1);
		}
	}
};

int main()
{
	TestCont *tc1 = new TestCont;
	tc1->mutex = new_ProxyMutex();
	TestCont *tc2 = new TestCont;
	tc2->mutex = new_ProxyMutex();

	ink_thread tid1 = t1.start("ET_TASK1", NULL, NULL);
	//ink_thread tid2 = t2.start("ET_TASK2", NULL, NULL);

	t1.schedule_at(tc2, 2);
	t1.schedule_imm(tc1);

	DCont *dc = new DCont;
	dc->mutex = new_ProxyMutex();
	Event *e = new Event;
	e->init(dc, 0, 0);
	e->ethread = new EThread(e);
	e->mutex = e->continuation->mutex = e->ethread->mutex_ptr;
	e->ethread->start("ET_D", NULL, NULL);

	//the eventprocessor manager EThread.
	//the EThread manager Event.

	while(true)
	{
		sleep(20);
	}
	return 0;
}
